#include "shell.h"
#include <iostream>
#include <string>
#include <pthread.h>
#include <vector>
#include "mpi.h"

using namespace std;

Shell::Shell()
{
    
}



void Shell::run()
{
  string command, data1, data2;
  command = data1 = data2 = "";
  int rank, tag = 1;
  int position = 0;
  char buffer[310];

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  bool quit = false;
  vector <string> input(3, "");

  while(!quit)
  {
    position = 0;
    cin >> command;
    
    if(command == "list")
    {
      input[0] = "list"; input[1] = ""; input[2] = "";
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }
      
      /*
      MPI_Pack(&a, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);

      MPI_Pack(&b, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&c, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);

      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      
    }
    else if(command == "quit")
    {
      input[0] = "quit"; input[1] = ""; input[2] = "";
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }
      
      /*
      MPI_Pack(&a, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&b, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&c, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;

      quit = true;
      return;
    }
    else if(command == "create")
    {
      cin >> data1;
      input[0] = "create"; input[1] = data1; input[2] = "";
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "load")
    {
      cin >> data1;
      input[0] = "load"; input[1] = data1; input[2] = "";
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "save")
    {
      cin >> data1;
      input[0] = "save"; input[1] = data1; input[2] = "";
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "insert")
    {
      cin >> data1;
      input[0] = "insert"; input[1] = data1; input[2] = "";
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "delete")
    {
      cin >> data1;
      input[0] = "delete"; input[1] = data1; input[2] = "";
      //Mpi data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "buy")
    {
      cin >> data1 >> data2;
      input[0] = "buy"; input[1] = data1; input[2] = data2;
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "sell")
    {
      cin >> data1 >> data2;
      input[0] = "sell"; input[1] = data1; input[2] = data2;
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "printi")
    {
      cin >> data1;
      input[0] = "printi"; input[1] = data1; input[2] = "";
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "printo")
    {
      cin >> data1;
      input[0] = "printo"; input[1] = data1; input[2] = "";
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "kill")
    {
      cin >> data1;
      input[0] = "kill"; input[1] = data1; input[2] = "";
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "srun")
    {
      cin >> data1 >> data2;
      input[0] = "srun"; input[1] = data1; input[2] = data2;
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else if(command == "prun")
    {
      cin >> data1 >> data2;
      input[0] = "prun"; input[1] = data1; input[2] = data2;
      //MPI data to server
      const char* string0 = input[0].c_str();
      const char* string1 = input[1].c_str();
      const char* string2 = input[2].c_str();

      char a[100];
      char b[100];
      char c[100];
      for(unsigned int i = 0; i < input[0].length() + 1; ++i)
      {
	a[i] = string0[i];
      }
      for(unsigned int i = 0; i < input[1].length() + 1; i++)
      {
	b[i] = string1[i];
      }
      for(unsigned int i = 0; i < input[2].length() + 1; i++)
      {
	c[i] = string2[i];
      }

      /*
      MPI_Pack(&string0, input[0].length(), MPI_CHAR, buffer, 100, 
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string1, input[1].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&string2, input[2].length(), MPI_CHAR, buffer, 100,
	       &position, MPI_COMM_WORLD);
      MPI_Pack(&rank, 1, MPI_INT, buffer, 10, &position, MPI_COMM_WORLD);
      */

      MPI_Send(&a, input[0].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&b, input[1].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
      MPI_Send(&c, input[2].length() + 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
      tag++;
    }
    else
    {
      //cout << "Invalid Command!" << endl;
      //Error log??
    }
  }

}

